"""
Grave! Important! Важно!

Proletoj el ĉiuj landoj, unuiĝu!
Workers of the world, unite!
Пролетарии всех стран, соединяйтесь!

https://tkom.pro
"""

from django.db.models import F
from django.conf import settings
from rest_framework import serializers
from rest_framework.reverse import reverse as rfreverse
from muroj.models import *
from main.models import Uzanto
from urllib.parse import urljoin
import re


class AbsoluteURLMixin:
    def _media_url(self, relative_url):
        return self.context.get('request').build_absolute_uri(urljoin(settings.MEDIA_URL, relative_url))

    def _object_url(self, relative_url):
        return self.context.get('request').build_absolute_uri(relative_url)


class MurojUzantoSerializer(serializers.Serializer, AbsoluteURLMixin):
    id = serializers.IntegerField()
    uuid = serializers.UUIDField()
    unua_nomo = serializers.StringRelatedField()
    familinomo = serializers.StringRelatedField()
    avataro_bildo = serializers.SerializerMethodField()
    avataro_bildo_min = serializers.SerializerMethodField()
    url = serializers.SerializerMethodField()

    def get_avataro_bildo(self, obj):
        return self._media_url(obj.avataro_bildo)

    def get_avataro_bildo_min(self, obj):
        return self._media_url(obj.avataro_bildo_min)

    def get_url(self, obj):
        return self._object_url(obj.get_absolute_url())


class MurojEnskriboBildoSerializer(serializers.Serializer, AbsoluteURLMixin):
    uuid = serializers.UUIDField()
    bildo = serializers.SerializerMethodField()

    def get_bildo(self, obj):
        relative_url = str(obj.bildo)
        return self._media_url(relative_url)


class MurojEnskriboSerializer(serializers.Serializer, AbsoluteURLMixin):
    id = serializers.IntegerField()
    uuid = serializers.UUIDField()
    posedanto_id = serializers.UUIDField()
    nomo = serializers.StringRelatedField()
    krea_dato = serializers.DateTimeField()
    teksto = serializers.StringRelatedField()
    bildoj = serializers.SerializerMethodField()
    video = serializers.URLField()
    kovrilo_bildo = serializers.SerializerMethodField()
    avataro_bildo = serializers.SerializerMethodField()
    avataro_bildo_min = serializers.SerializerMethodField()
    autoro_montri = serializers.BooleanField()
    autoro = serializers.SerializerMethodField()
    komentoj_tuta = serializers.SerializerMethodField()
    komentoj = serializers.SerializerMethodField()
    interesoj_tuta = serializers.IntegerField()
    mia_interese = serializers.BooleanField()
    url = serializers.SerializerMethodField()
    detail = serializers.SerializerMethodField()

    class Meta:
        model_cache = {}

    def __get_komento_manager(self, obj):
        if self.Meta.model_cache.get(obj.__class__) is None:
            if isinstance(obj, MurojSociaprojektoEnskribo):
                self.Meta.model_cache[obj.__class__] = {
                    'komentoj': 'murojsociaprojektoenskribokomento_set',
                    'bildoj': 'murojsociaprojektoenskribobildo_set'
                }
            elif isinstance(obj, MurojSovetoEnskribo):
                self.Meta.model_cache[obj.__class__] = {
                    'komentoj': 'murojsovetoenskribokomento_set',
                    'bildoj': 'murojsovetoenskribobildo_set'
                }
            elif isinstance(obj, MurojGrupoEnskribo):
                self.Meta.model_cache[obj.__class__] = {
                    'komentoj': 'murojgrupoenskribokomento_set',
                    'bildoj': 'murojgrupoenskribobildo_set'
                }
            elif isinstance(obj, MurojOrganizoEnskribo):
                self.Meta.model_cache[obj.__class__] = {
                    'komentoj': 'murojorganizoenskribokomento_set',
                    'bildoj': 'murojorganizoenskribobildo_set'
                }

        return self.Meta.model_cache.get(obj.__class__)

    def get_autoro(self, obj):
        autoro = (Uzanto.objects
                  .annotate(avataro_bildo=F('fotoj_fotojuzantojavataro_posedanto__bildo'),
                            avataro_bildo_min=F('fotoj_fotojuzantojavataro_posedanto__bildo_min'))
                  .filter(id=obj.autoro_id))
        serializer = MurojUzantoSerializer(autoro.first(), many=False, context=self.context)
        return serializer.data

    def get_bildoj(self, obj):
        manager = self.__get_komento_manager(obj).get('bildoj')

        if manager is None:
            return ''

        bildoj = getattr(obj, manager).filter(forigo=False, arkivo=False)
        serializer = MurojEnskriboBildoSerializer(bildoj, many=True, context=self.context)
        return serializer.data

    def get_avataro_bildo(self, obj):
        return self._media_url(obj.avataro_bildo)

    def get_avataro_bildo_min(self, obj):
        return self._media_url(obj.avataro_bildo_min)

    def get_kovrilo_bildo(self, obj):
        return self._media_url(obj.kovrilo_bildo)

    def get_komentoj_tuta(self, obj):
        manager = self.__get_komento_manager(obj).get('komentoj')

        if manager is None:
            return ''

        komentoj_tuta = getattr(obj, manager).filter(forigo=False, arkivo=False)
        return komentoj_tuta.count()

    def get_komentoj(self, obj):
        kwargs = {'enskribo_uuid': obj.uuid}
        return self._object_url(rfreverse('api:muro_komentoj-list', kwargs=kwargs,
                                          request=self.context.get('request')))

    def get_url(self, obj):
        return self._object_url(obj.get_absolute_url())

    def get_detail(self, obj):
        kwargs = {'komunumo_uuid': obj.posedanto_id, 'uuid': obj.uuid}
        return self._object_url(rfreverse('api:muro_komunumo-detail', kwargs=kwargs,
                                          request=self.context.get('request')))


class MurojEnskriboKomentoSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    uuid = serializers.UUIDField()
    krea_dato = serializers.DateTimeField()
    teksto = serializers.StringRelatedField()
    autoro = serializers.SerializerMethodField()

    def get_autoro(self, obj):
        autoro = (Uzanto.objects
                  .annotate(avataro_bildo=F('fotoj_fotojuzantojavataro_posedanto__bildo'),
                            avataro_bildo_min=F('fotoj_fotojuzantojavataro_posedanto__bildo_min'))
                  .filter(id=obj.autoro_id))
        serializer = MurojUzantoSerializer(autoro.first(), many=False, context=self.context)
        return serializer.data
